﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using ScreenManagement;
using EventFlowLibrary.GameStructure;

namespace EventFlowLibrary.LevelComponents
{
    public sealed class Letter : DrawableGameComponent
    {
        /// <summary>
        /// Whether the journal is currently displayed
        /// </summary>
        public bool IsShown = false;

        /// <summary>
        /// Spritebatch to draw necessary items.
        /// </summary>
        private SpriteBatch spriteBatch;

        /// <summary>
        /// Font for journal entries
        /// </summary>
        private SpriteFont font;

        /// <summary>
        /// Background texture of the letter
        /// </summary>
        private Texture2D letterTexture;

        private Dictionary<string, string> letters;
        internal string shownLetter;
        private const string backText = "Put Away";
        private Texture2D bButton;

        /// <summary>
        /// The top corners of the letter texture in screen coordinates.
        /// </summary>
        private int letterTopX, letterTopY;

        /// <summary>
        /// The bottom coordinates of the screen, with 10% pad
        /// </summary>
        private Rectangle bottomCorner;

        /// <summary>
        /// Corner for the text
        /// </summary>
        private Vector2 bottomCornerText;

        /// <summary>
        /// Our current fade value, between 0.0f and 1.0f
        /// </summary>
        private float alphaFade;

        /// <summary>
        /// Fade in/out rate of journal
        /// </summary>
        private const float alphaFadeRate = 0.005f;

        /// <summary>
        /// Owner text manager
        /// </summary>
        private TextManagement textManager;

        internal Letter(Game _game, ScreenManager _screenManager, TextManagement _textManager)
            : base(_game)
        {
            this.spriteBatch = _screenManager.SpriteBatch;

            this.alphaFade = 0.0f;

            this.DrawOrder = int.MaxValue;

            textManager = _textManager;
        }

        protected override void LoadContent()
        {
            // TODO make global content manager?
            ContentManager content = new ContentManager(this.Game.Content.ServiceProvider, "Content");

            font = content.Load<SpriteFont>("Fonts/gamefontSmall");
            letterTexture = content.Load<Texture2D>("Textures/Materials/paper3");
            bButton = content.Load<Texture2D>("Textures/Buttons/xboxControllerButtonB");

            // Center the texture, assuming a 1280x720 screen
            letterTopX = 640 - (letterTexture.Width / 2);
            letterTopY = 360 - (letterTexture.Height / 2);

            // Get the back draw information, based on 1280x720 screen
            bottomCorner = new Rectangle(1280 - 128 - 32, 720 - 72 - 32, 32, 32);
            bottomCornerText = new Vector2(bottomCorner.X - 10 - font.MeasureString(backText).X, 720 - 72 - 32);

            // Set our letters
            // TODO ugly hack just to get it done. All these references will break the game if changed either here or in game constructor.
            string[] letterNames = { "Letter1", "Letter2", "Letter3" };
            string[] letters = {"[Addressed to Miss Havisham]\n" +
                                "\n\n\n" + 
                                "My Dearest Sweetest Friend, I write to you\n" +
                                "today full of joy and anticipation...  My dear\n" +
                                "Reynaldo has promised to come see me today,\n" +
                                "to ask me something... I have long been waiting\n" +
                                "and hoping for this day!  My dearest love is\n" +
                                "going to make me the happiest woman on earth\n" +
                                "and set everything right!  ...Oh, my dear, I will\n" +
                                "write you as soon as I may with the good news.\n" + 
                                "\n" +
                                "Miriam",
                                "[Addressed to Miss Havisham]\n" +
                                "\n" +
                                "My dear friend, I can hardly hold the pen, I am\n" +
                                "so weak and tired of weeping. You must\n" + 
                                "disregard the last letter.  I was wrong,\n " +
                                "completely wrong, and I will confide only to\n" +
                                "you that he has broken more than my heart.\n" +
                                "What I thought was love, was not.  What I\n" +
                                "thought was honor was dishonor. I have been\n" +
                                "completely thrown over.  He made me promises\n" +
                                "he did not keep. He has taken everything away\n" +
                                "from me and disappeared forever... How could\n" +
                                "I have been such a fool?  How could I have\n" +
                                "fallen for such lies and looks, such sighs\n" +
                                "and caresses that have led to nothing but\n" +
                                "complete devastation? All my hopes and dreams\n" +
                                "are dashed.\n" +
                                "I have no future, no hope.\n" +
                                "Pray for me that I am not lost.\n" +
                                "\n" +
                                "Miriam",
                                "[Addressed to Miss Havisham]\n" +
                                "\n\n\n\n" + 
                                "Miss Havisham, I am sorry to be the bearer of\n" + 
                                "tragic news. Sweet Miriam has ended her life. \n" +
                                "No one can understand why. She was so happy\n" +
                                "only a short while ago. Dear Reynaldo is mad\n" +
                                "with grief, it is almost too much to witness;\n" +
                                "he loved her so much..."};
            CreateLetters(letterNames, letters);

            base.LoadContent();
        }

        /// <summary>
        /// Construct our letters
        /// </summary>
        /// <param name="_letterNames"></param>
        /// <param name="_textManager"></param>
        private void CreateLetters(string[] _letterNames, string[] _letters)
        {
            letters = new Dictionary<string, string>(_letterNames.Length);

            for (int i = 0; i < _letterNames.Length; i++)
            {
                letters.Add(_letterNames[i], _letters[i]);
            }
        }

        public override void Draw(GameTime gameTime)
        {
            if (IsShown)
            {
                // Change our fade
                alphaFade = Math.Min(1.0f, alphaFade + gameTime.ElapsedGameTime.Milliseconds * alphaFadeRate);
            }
            else if (alphaFade > 0)
            {
                // Change our fade
                alphaFade = Math.Max(0.0f, alphaFade - gameTime.ElapsedGameTime.Milliseconds * alphaFadeRate);
            }

            if (alphaFade > 0.0f)
            {
                spriteBatch.Begin();

                spriteBatch.Draw(letterTexture, new Rectangle(letterTopX, letterTopY, letterTexture.Width, letterTexture.Height), Color.White * alphaFade);

                // Draw the letter
                spriteBatch.DrawString(font, letters[shownLetter], new Vector2(letterTopX + 10, letterTopY + 10), Color.Black * alphaFade);

                // Draw the Back button and text
                if (textManager.CurrentEvents.Count == 0)
                {
                    spriteBatch.Draw(bButton, bottomCorner, Color.White);
                    spriteBatch.DrawString(font, backText, bottomCornerText, Color.White);
                }

                spriteBatch.End();

                //base.Draw(gameTime);
            }
        }

        //public override void Update(GameTime gameTime)
        //{
        //    base.Update(gameTime);
        //}
    }
}
